#include <dlfcn.h>
#include "ReaderDemo.h"

#define second 1000*1000

char lib_path[256] = {0};

void *dHandle = NULL;
typedef long(*open_device)(void);
typedef long(*close_device)(void);
typedef long(*power_on)(unsigned char, unsigned char*);
typedef long(*power_off)(unsigned char);
typedef long(*get_status)(unsigned char);
typedef long(*send_adpu)(unsigned char, long, unsigned char*, unsigned char*);
typedef long(*lib_info)(char*);
typedef long(*get_device_id)(char*);
typedef void(*set_path)(char*);
typedef long(*syn_get_data)(char*,char*);
//typedef long(*syn_get_bmp)(unsigned char*,char*);
typedef long(*syn_get_cert_info)(int,char*,char*,char*);
typedef long(*get_lib_version)(char*);
typedef long(*get_device_version)(char*);
typedef long(*get_scanner)(int, long, unsigned char*);
typedef long(*get_keyboard)(int, long, unsigned char*);
typedef long(*get_magetictrack)(int, long, unsigned char*);
typedef long(*beep)(long);
typedef long(*rf_set_type)(char);
typedef long(*rf_set_antenna)(char);
typedef long (*rf_activate_card)(int,unsigned char*,unsigned char*);

open_device			ICC_Reader_Open;
close_device		ICC_Reader_Close;
power_on			ICC_Reader_PowerOn;
power_off			ICC_Reader_PowerOff;
get_status			ICC_Reader_GetStatus;
send_adpu			ICC_Reader_Application;
lib_info			ICC_Reader_Libinfo;
get_device_id		ICC_Reader_GetDevID;
set_path			Set_Path;
syn_get_data		Syn_Get_Data;
//syn_get_bmp			Syn_Get_BMP;
syn_get_cert_info	ICC_Reader_CertInfo;
get_lib_version		Get_Lib_Version;
get_device_version	Get_Device_Version;
get_scanner			Get_Scanner;
get_keyboard		Get_KeyBoard;
get_magetictrack	Get_MagneticTrack;
beep				ICC_Reader_Beep;
rf_set_type			Rf_Set_Type;
rf_set_antenna		Rf_Set_Antenna;
rf_activate_card	Rf_Activate_Card;

long Load_Lib(void)
{

	dHandle = dlopen("/system/lib/plugin/libswanlink_reader.z.so",RTLD_NOW);
	if(!dHandle){
		printf("dlopen failed :%s\n",dlerror());
		return -1;
	}
	ICC_Reader_Open = (open_device)dlsym(dHandle,"ICC_Reader_Open");
	ICC_Reader_Close = (close_device)dlsym(dHandle,"ICC_Reader_Close");
	ICC_Reader_PowerOn = (power_on)dlsym(dHandle,"ICC_Reader_PowerOn");
	ICC_Reader_PowerOff = (power_off)dlsym(dHandle,"ICC_Reader_PowerOff");
	ICC_Reader_GetStatus = (get_status)dlsym(dHandle,"ICC_Reader_GetStatus");
	ICC_Reader_Application = (send_adpu)dlsym(dHandle,"ICC_Reader_Application");
	ICC_Reader_Libinfo = (lib_info)dlsym(dHandle,"ICC_Reader_Libinfo");
	ICC_Reader_GetDevID = (get_device_id)dlsym(dHandle,"ICC_Reader_GetDevID");
	Set_Path = (set_path)dlsym(dHandle,"Set_Path");
	Syn_Get_Data = (syn_get_data)dlsym(dHandle,"Syn_Get_Data");
	//Syn_Get_BMP = (syn_get_bmp)dlsym(dHandle,"Syn_Get_BMP");
	ICC_Reader_CertInfo = (syn_get_cert_info)dlsym(dHandle,"ICC_Reader_CertInfo");
	Get_Lib_Version = (get_lib_version)dlsym(dHandle,"Get_Lib_Version");
	Get_Device_Version = (get_device_version)dlsym(dHandle,"Get_Device_Version");

	Get_Scanner = (get_scanner)dlsym(dHandle,"Get_Scanner");
	Get_KeyBoard = (get_keyboard)dlsym(dHandle,"Get_KeyBoard");
	Get_MagneticTrack = (get_magetictrack)dlsym(dHandle,"Get_MagneticTrack");
	ICC_Reader_Beep = (beep)dlsym(dHandle,"ICC_Reader_Beep");
	Rf_Set_Type = (rf_set_type)dlsym(dHandle,"Rf_Set_Type");
	Rf_Set_Antenna = (rf_set_antenna)dlsym(dHandle,"Rf_Set_Antenna");
	Rf_Activate_Card = (rf_activate_card)dlsym(dHandle,"Rf_Activate_Card");

	char *perror = dlerror();
	if(perror)
	{
		printf("load symbol failed:%s\n", perror);
		return -3;
	}
	return 0;
}

char g_Err[64] = {0};
char* Error_Mapping(long error_code)
{
	sprintf(g_Err, "error: %d", (int)error_code);
	return g_Err;
#if 0
    int len = 64;
	char* Error_Info = (char*)malloc(sizeof(char) * len);
	memset(Error_Info, 0, sizeof(char) * len);

	switch (error_code)
	{
		case 1:
			snprintf(Error_Info, len, "1|有卡已上电");
			break;
		case 0:
			snprintf(Error_Info, len, "0|操作成功");
			break;
		case -1:
			snprintf(Error_Info, len, "-1|卡类型不符");
			break;
		case -2:
			snprintf(Error_Info, len, "-2|无卡或逻辑卡密码非法");
			break;
		case -3:
			snprintf(Error_Info, len, "-3|有卡未上电");
			break;
		case -4:
			snprintf(Error_Info, len, "-4|卡片无应答");
			break;
		case -6:
			snprintf(Error_Info, len, "-6|读写器返回数据失败");
			break;
		case -7:
			snprintf(Error_Info, len, "-7|逻辑卡未选择卡类型");
			break;
		case -8:
			snprintf(Error_Info, len, "-8|逻辑卡未校验密码");
			break;
		case -11:
			snprintf(Error_Info, len, "-11|读写器连接错误");
			break;
		case -12:
			snprintf(Error_Info, len, "-12|读写器设备未连接");
			break;
		case -13:
			snprintf(Error_Info, len, "-13|不支持该命令");
			break;
		case -14:
			snprintf(Error_Info, len, "-14|命令参数错误");
			break;
		case -15:
			snprintf(Error_Info, len, "-15|信息检验或出错");
			break;
		case -16:
			snprintf(Error_Info, len, "-16|未设置密码键盘工作模式或扫描窗超时");
			break;
		case -17:
			snprintf(Error_Info, len, "-17|密码键盘设置错误");
			break;
		case -18:
			snprintf(Error_Info, len, "-18|未创建句柄");
			break;
		case -19:
			snprintf(Error_Info, len, "-19|密码键盘超时");
			break;
		case -20:
			snprintf(Error_Info, len, "-20|读磁卡信息超时");
			break;
		case -22:
			snprintf(Error_Info, len, "-22|接收业务终端数据的长度错误");
			break;
		case -23:
			snprintf(Error_Info, len, "-23|接收业务终端的命令错误");
			break;
		case -24:
			snprintf(Error_Info, len, "-24|越权操作");
			break;
		case -25:
			snprintf(Error_Info, len, "-25|无法识别的错误");
			break;
		case -26:
			snprintf(Error_Info, len, "-26|证卡时认证 SAM-V 失败");
			break;
		case -27:
			snprintf(Error_Info, len, "-27|信息验证错误");
			break;
		case -28:
			snprintf(Error_Info, len, "-28|PC 接收超时(在规定的时间内未接收到规定长度的数据)");
			break;
		case -29:
			snprintf(Error_Info, len, "-29|无法识别的卡类型");
			break;
		case -30:
			snprintf(Error_Info, len, "-30|读证卡操作失败");
			break;
		case -31:
			snprintf(Error_Info, len, "-31|SAM-V 自检失败不能接收命令");
			break;
		case -32:
			snprintf(Error_Info, len, "-32|SAM-V 没经过授权，无法使用");
			break;
		case -33:
			snprintf(Error_Info, len, "-33|寻找证卡失败");
			break;
		case -34:
			snprintf(Error_Info, len, "-34|选取证卡失败");
			break;
		case -35:
			snprintf(Error_Info, len, "-35|证卡中此项无内容");
			break;
		case -36:
			snprintf(Error_Info, len, "-36|其他未知错誤");
			break;
		case -37:
			snprintf(Error_Info, len, "-37|调用解码包错误");
			break;
		case -38:
			snprintf(Error_Info, len, "-38|调用 sdtapi.dll 错误");
			break;
		case -39:
			snprintf(Error_Info, len, "-39|wlt 文件后缀错误");
			break;
		case -40:
			snprintf(Error_Info, len, "-40|wlt 文件打开错误");
			break;
		case -41:
			snprintf(Error_Info, len, "-41|wlt 文件格式错误");
			break;
		case -42:
			snprintf(Error_Info, len, "-42|软件未授权或非接触式卡超时");
			break;
		case -43:
			snprintf(Error_Info, len, "-43|设备连接錯誤或选非接触式卡失败");
			break;
		case -44:
			snprintf(Error_Info, len, "-44|相片解码错误或非接触式卡防冲突失败");
			break;
		case -45:
			snprintf(Error_Info, len, "-45|非接触式卡校验失败");
			break;
		case -46:
			snprintf(Error_Info, len, "-46|非接触式卡读数据失败");
			break;
		case -47:
			snprintf(Error_Info, len, "-47|非接触式卡写数据失败");
			break;
		case -48:
			snprintf(Error_Info, len, "-48|非接触式卡休眠失败");
			break;
		case -49:
			snprintf(Error_Info, len, "-49|非接触式卡增减值失败");
			break;
		case -50:
			snprintf(Error_Info, len, "-50|非接触式卡传值失败");
			break;
		default:
			snprintf(Error_Info, len, "-%d|未知错误",(int)error_code);
			break;
	}
	//memcpy_s(Info, sizeof(Info), Error_Info, strlen(Error_Info));
	//free(Error_Info);
	return Error_Info;
#endif
}

void func_connect(void)
{
	int ret = 0;
	unsigned char buffer[64]={0};

    ret = ICC_Reader_Open();
    if(ret<0)
    {
        printf("连接读写器失败:%s \r\n",Error_Mapping(ret));
        //return -1;
    }
	else 
		printf("设备已连接 \r\n");

	//printf("\r\n*****设备信息*****\r\n");

	memset(buffer,0,64);
	ret = ICC_Reader_GetDevID((char*)buffer);
	printf ("%d",ret);
    printf("当前设备终端设备号: ");
	
	for(int i=0;i<ret;i++)
        printf("%02x",buffer[i]);
    printf("\r\n");

	memset(buffer,0,64);
	ret = Get_Device_Version((char*)buffer);
    printf("当前设备固件版本:%s \r\n",buffer);

	return;
}

void func_disconnect(void)
{
	int ret = 0;
	
	ret = ICC_Reader_Close();
    if(ret<0)
    {
        printf("断开读写器通讯失败:%s \r\n",Error_Mapping(ret));
        //return -1;
    }
	else 
		printf("设备已断开\r\n");

	return;
}

void func_beep(void)
{
	int ret = 0;
	int time = 9;

	ret = ICC_Reader_Beep(time);
	if(ret<0)
        printf("调用蜂鸣器失败:%s \r\n",Error_Mapping(ret));
	else
		printf("操作成功\r\n");

	return;
}

void func_CPUcard_test(unsigned char card_slot)
{
	int ret = 0;
	unsigned char s_len = 5;
	unsigned char buffer[64]={0};
	unsigned char command[64] ={0x00,0x84,0x00,0x00,0x08};

 	ret = ICC_Reader_GetStatus(card_slot);
    printf("当前卡状态:%s \r\n",Error_Mapping(ret));

    memset(buffer,0,64);
    ret = ICC_Reader_PowerOn(card_slot,buffer);
    if(ret<0)
        printf("上电失败:%s \r\n",Error_Mapping(ret));	
    else
	{
        printf("复位信息: ");
        for(int i=0;i<ret;i++)
            printf("%02x",buffer[i]);
        printf("\r\n");
    }

	ret = ICC_Reader_GetStatus(card_slot);
    printf("当前卡状态:%s \r\n",Error_Mapping(ret));

    memset(buffer,0,64);
    ret = ICC_Reader_Application(card_slot,s_len,command,buffer);

    if(ret<0)
        printf("取随机数失败:%s \r\n",Error_Mapping(ret));

    else
    {
        printf("取随机数信息: ");
        for(int i=0;i<ret;i++)
            printf("%02x",buffer[i]);
        printf("\r\n");
    }

	ret = ICC_Reader_PowerOff(card_slot);
    printf("卡下电操作:%s \r\n",Error_Mapping(ret));

	ret = ICC_Reader_GetStatus(card_slot);
    printf("当前卡状态:%s \r\n",Error_Mapping(ret));

	return;
}

void func_magnetic_test()
{
	int ret = 0;
	int mode = 0x01;
	long timeout = 10;
	unsigned char *buffer = (unsigned char*)malloc(sizeof(char)*1024);
	memset(buffer,0,sizeof(char)*1024);

	ret = Get_MagneticTrack(mode,timeout,buffer);
	if(ret<0)
		printf("rfcard read failed:%s \r\n",Error_Mapping(ret));

	else
		printf("rfcard info: %s\r\n",buffer);

	free(buffer);
	return;
}

void func_Certcard_test()
{
	int ret = 0;
	int index = 0;	//index: 0:no_photo，no_base64；1:no_photo，base64；2:photo，no_base64；3:photo，base64
	char* path  = (char*)malloc(sizeof(char)*256);
	memset(path,0,256);
	memset(path,0,256);
	strcpy(path,"");
	char *data = (char*)malloc(sizeof(char)*1024);
	memset(data,0,sizeof(char)*1024);
	char *image_data = (char*)malloc(sizeof(char)*102*128*3);
	memset(image_data,0,sizeof(char)*102*128*3);

	strcpy(lib_path,"/data/finance/");
	Set_Path(lib_path);
	ret = ICC_Reader_CertInfo(index,path,image_data,data);	

	if(ret<0)
		printf("id card read failed:%s \r\n",Error_Mapping(ret));

	else
		printf("ret = %d\r\nid card info: %s\r\n",ret,data);

	free(image_data);
	free(data);
	free(path);	
	return;
}

void func_code_test()
{
	int ret = 0;
	int voice = 0;
	long timeout = 30;
	unsigned char *buffer = (unsigned char*)malloc(sizeof(char)*1024);
	memset(buffer,0,sizeof(char)*1024);

	ret = Get_Scanner(voice, timeout,buffer);
	if(ret<0)
		printf("获取条码信息失败:%s \r\n",Error_Mapping(ret));

	else
		printf("条码信息: %s\r\n",buffer);

	free(buffer);
	return;
}

void func_keyboard_test(void)
{
	int ret = 0;
	int voice = 0x01;
	int timeout = 10;
	unsigned char buffer[64] = {0};

	ret = Get_KeyBoard(voice,timeout,buffer);
    if(ret<0)
        printf("获取键盘输入失败:%s \r\n",Error_Mapping(ret));	

    else
        printf("键盘输入: %s\r\n",buffer);

}

int main(void)
{
	long ret = 0;
	int index = 0;
    unsigned char slot = 0;
    char buff[64] = {0};

	ret = Load_Lib();
	if(ret < 0){
		printf("Load library failed! \r\n");
		return 0;	
	}
	else
		printf("library load success! \r\n");
	
	printf("\r\n***********************\r\n");
	ret = ICC_Reader_Libinfo(buff);
    printf("*current version:%s \r\n",buff);

	memset(buff,0,64);
	ret = Get_Lib_Version(buff);
    printf("*current so version:%s \r\n",buff);
	printf("***********************\r\n");
 	printf("\r\n");

	Loop:

	printf("\r\n--------function--------\r\n 0:exit 1:connect 2:disconnect 3:beep test \r\n 4:main card test 5:SAM1 test 6:SAM2 test 7:pcpu test \r\n 8:rfcard test 9:idcard test 10:scanner test 11:keyboard test \r\n----------------------------\r\n");
	printf("please input index:");
	scanf("%d",&index);

	switch (index)
	{
		case 0:
			exit(0);
			break;
		case 1:
			printf("\r\n*********connect*********\r\n");
			func_connect();
			break;
		case 2:
			printf("\r\n*********disconnect*********\r\n");
			func_disconnect();
			break;
		case 3:
			printf("\r\n*********beep test*********\r\n");
			func_beep();
			break;
		case 4:
			printf("\r\n*********main test*********\r\n");
			slot = 0x01;
			func_CPUcard_test(slot);
			break;
		case 5:
			printf("\r\n*********SAM1 test*********\r\n");
			slot = 0x11;
			func_CPUcard_test(slot);
			break;
		case 6:
			printf("\r\n*********SAM2 test*********\r\n");
			slot = 0x12;
			func_CPUcard_test(slot);
			break;
		case 7:
			printf("\r\n*********CPU test*********\r\n");
			slot = 0x31;
			func_CPUcard_test(slot);
			break;
		case 8:
			printf("\r\n*********rfcard test*********\r\n");
			func_magnetic_test();
			break;
		case 9:
			printf("\r\n*********idcard test*********\r\n");
			func_Certcard_test();
			break;
		case 10:
			printf("\r\n*********scnner test*********\r\n");
			func_code_test();
			break;
		case 11:
			printf("\r\n*********keyboard test*********\r\n");
			func_keyboard_test();
			break;
		default:
			printf("输入有误，请重新输入\r\n");
			break;
	}
	
	goto Loop;
    
}
